<template>
    <div class="h-paging-container">
        <!-- 顶部固定插槽 -->
        <div class="fixed-top">
            <slot name="top"></slot>
        </div>

        <!-- 内容区域包装器 -->
        <div class="content-wrapper">
            <!-- 下拉刷新区域 -->
            <div class="pull-refresh-area" :class="{ 'refreshing': isRefreshing }" ref="pullRefreshArea">
                <div class="pull-text">{{ refreshText }}</div>
            </div>

            <!-- 内容区域 -->
            <div class="content-area" ref="scrollContainer" @touchstart="handleTouchStart" @touchmove="handleTouchMove"
                @touchend="handleTouchEnd" @scroll="handleScroll">
                <slot></slot>
                <!-- 加载更多区域 -->
                <div v-if="enableLoadMore">
                    <div class="loading-more" v-if="hasMore">
                        <span>{{ loadingText }}</span>
                    </div>
                    <div class="loading-more" v-else="hasMore">
                        <span>无更多数据</span>
                    </div>
                </div>

            </div>
        </div>

        <!-- 底部固定插槽 -->
        <div class="fixed-bottom">
            <slot name="bottom"></slot>
        </div>
    </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, defineModel } from 'vue'
import ArrayUtil from '../../util/ArrayUtil'

// Props 定义
interface Props {
    distance?: number
    threshold?: number
    defaultPageNumber?: number
    defaultPageSize?: number
    enableLoadMore?: boolean
    enableRefresh?: boolean
}

const model = defineModel<any[]>({ required: true, default: [] })

const props = withDefaults(defineProps<Props>(), {
    distance: 50,  // 下拉刷新的触发距离
    threshold: 100, // 上拉加载的触发阈值
    defaultPageSize: 10, // 默认每页显示的条数
    defaultPageNumber: 0,// 默认页码
    enableLoadMore: true,
    enableRefresh: true
})

// Emits 定义
const emit = defineEmits<{
    query: [pageNumber: number, pageSize: number]
}>()

// 状态管理
const startY = ref(0)
const currentY = ref(0)
const isRefreshing = ref(false)
const pullRefreshArea = ref<HTMLElement | null>(null)
const scrollContainer = ref<HTMLElement | null>(null)
const loading = ref(false)
const hasMore = ref(false)
const pageNumber = ref(props.defaultPageNumber)

// 计算属性
const refreshText = computed(() => {
    if (isRefreshing.value) return '刷新中...'
    const distance = currentY.value - startY.value
    return distance >= props.distance ? '释放刷新' : '下拉刷新'
})

const loadingText = computed(() => {
    return loading.value ? '加载中...' : '上拉加载更多'
})

onMounted(() => {
    reload()
})

// 触摸事件处理
const handleTouchStart = (e: TouchEvent) => {
    if (scrollContainer.value?.scrollTop === 0) {
        startY.value = e.touches[0].pageY
    }
}

const handleTouchMove = (e: TouchEvent) => {
    if (!props.enableRefresh) return
    if (startY.value === 0 || isRefreshing.value) return

    currentY.value = e.touches[0].pageY
    const distance = currentY.value - startY.value

    if (distance > 0 && scrollContainer.value?.scrollTop === 0) {
        e.preventDefault()
        const moveDistance = Math.min(distance / 2, props.distance * 1.5)
        if (pullRefreshArea.value) {
            pullRefreshArea.value.style.height = `${moveDistance}px`
        }
        if (scrollContainer.value) {
            scrollContainer.value.style.transform = `translateY(${moveDistance}px)`
        }
    }
}

const handleTouchEnd = async () => {
    if (!props.enableRefresh) return
    if (startY.value === 0) return

    const distance = currentY.value - startY.value
    if (distance >= props.distance && !isRefreshing.value) {
        isRefreshing.value = true
        reload()
    }
    // 重置状态
    startY.value = 0
    currentY.value = 0
    if (pullRefreshArea.value) {
        pullRefreshArea.value.style.height = '0px'
    }
    if (scrollContainer.value) {
        scrollContainer.value.style.transform = 'translateY(0)'
    }
}

// 滚动事件处理
const handleScroll = () => {
    if (!scrollContainer.value || loading.value || !hasMore.value || !props.enableLoadMore) return
    const { scrollHeight, scrollTop, clientHeight } = scrollContainer.value
    if (scrollHeight - scrollTop - clientHeight <= props.threshold) {
        loading.value = true
        pageNumber.value = pageNumber.value + 1
        emit('query', pageNumber.value, props.defaultPageSize)
    }
}

// 提供刷新完成的方法
const refreshComplete = () => {
    isRefreshing.value = false
    if (scrollContainer.value) {
        scrollContainer.value.style.transform = 'translateY(0)'
    }
    if (pullRefreshArea.value) {
        pullRefreshArea.value.style.height = '0px'
    }
}

const complete = (datas: any[]) => {
    refreshComplete()
    let data1 = ArrayUtil.merge(model.value!, datas)
    model.value = data1
    hasMore.value = datas.length === props.defaultPageSize
    loading.value = false
}

const reload = () => {
    model.value.length = 0
    hasMore.value = false
    pageNumber.value = props.defaultPageNumber
    emit('query', props.defaultPageNumber, props.defaultPageSize)
}


// 暴露方法给父组件
defineExpose({
    complete,
    reload
})
</script>

<style scoped>
.h-paging-container {
    position: relative;
    height: 100%;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.fixed-top {
    position: relative;
    flex-shrink: 0;
    width: 100%;
    z-index: 100;
}

.fixed-bottom {
    position: relative;
    flex-shrink: 0;
    width: 100%;
    z-index: 100;
}

.content-wrapper {
    position: relative;
    flex: 1;
    overflow: hidden;
}

.pull-refresh-area {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 0;
    overflow: hidden;
    transition: height 0.2s;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: #f5f5f5;
    z-index: 99;
}

.pull-text {
    font-size: 14px;
    color: #666;
}

.content-area {
    height: 100%;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    position: relative;
    transition: transform 0.2s;
    will-change: transform;
}

.loading-more {
    padding: 15px 0;
    text-align: center;
    font-size: 14px;
    color: #666;
}

.refreshing .pull-text {
    animation: rotating 1s linear infinite;
}

@keyframes rotating {
    from {
        transform: rotate(0deg);
    }

    to {
        transform: rotate(360deg);
    }
}
</style>